#include "test_gpio_i2c.h"

 /**
  * @brief  Delay
  * @param  
  * @retval 
  */
static void Delay(__IO uint32_t nCount)	 //???????
{
	for(; nCount != 0; nCount--);
}


void IIC_SDA(uint8_t a)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	if(a)
	{
		GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
		GPIO_InitStruct.GPIO_OType = GPIO_OType_OD;
		GPIO_InitStruct.GPIO_Pin = DEBUG_IIC_SDA_PIN;
		GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
		GPIO_InitStruct.GPIO_Speed = GPIO_Low_Speed;
		GPIO_Init(DEBUG_IIC_SDA_GPIO_PORT,&GPIO_InitStruct);	
	}
	else
	{
		GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
		GPIO_InitStruct.GPIO_OType = GPIO_OType_OD;
		GPIO_InitStruct.GPIO_Pin = DEBUG_IIC_SDA_PIN;
		GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
		GPIO_InitStruct.GPIO_Speed = GPIO_Low_Speed;
		GPIO_Init(DEBUG_IIC_SDA_GPIO_PORT,&GPIO_InitStruct);	
	}
}
	

//IIC
void IIC_SCL_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
	GPIO_InitStruct.GPIO_OType = GPIO_OType_OD;
	GPIO_InitStruct.GPIO_Pin = DEBUG_IIC_SCL_PIN;
	GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_InitStruct.GPIO_Speed = GPIO_Low_Speed;
	GPIO_Init(DEBUG_IIC_SCL_GPIO_PORT,&GPIO_InitStruct);						
}

//IIC
void IIC_Start(void)
{
	IIC_SDA(1);
	Delay(40);
	SDA_OUT(1);
	SCL_OUT(1);
	Delay(40);
	SDA_OUT(0);
	Delay(40);
	SCL_OUT(0);
	Delay(40);
}

//IIC
void IIC_Stop(void)
{
	IIC_SDA(1);
	Delay(40);
	SDA_OUT(0);
	Delay(40);
	SCL_OUT(0);
	Delay(40);
  SCL_OUT(1);
  Delay(40);
	SDA_OUT(1);
	Delay(40);
	
}
//ACK
void IIC_Ack(void)
{
	IIC_SDA(1);
	Delay(40);
	SCL_OUT(0);
	Delay(40);
	SDA_OUT(0);
	Delay(40);
	SCL_OUT(1);
	Delay(40);
	SCL_OUT(0);
	Delay(40);
}
	
//NACK
void IIC_NAck(void)
{
	IIC_SDA(1);
	Delay(40);
	SCL_OUT(0);
	Delay(40);
	SDA_OUT(1);
	Delay(40);
	SCL_OUT(1);
	Delay(40);
	SCL_OUT(0);
	Delay(40);
}

//
uint8_t IIC_Wait_Ack(void)
{
	uint8_t Time=0;
	SDA_OUT(1);
	Delay(40);
	IIC_SDA(0);
	Delay(40);
	SCL_OUT(1);
	while(GPIO_ReadInputDataBit(DEBUG_IIC_SDA_GPIO_PORT,DEBUG_IIC_SDA_PIN))
	{
		Time++;
		if(Time>250)
		{
			IIC_Stop();
			return 1;
		}
	}
	Delay(40);
	SCL_OUT(0);
	return 0;
}
	
//IIC_Send_Byte
void IIC_Send_Byte(uint8_t txd)
{
	uint8_t t;
	IIC_SDA(1);
	SCL_OUT(0);
	Delay(40);
	for(t=0;t<8;t++)
	{
		if((txd&0x80)== 0x80)
			SDA_OUT(1);
		else
			SDA_OUT(0);
		
		txd<<=1;
		Delay(40);
		SCL_OUT(1);
		Delay(80);
		SCL_OUT(0);
		Delay(40);
	}
}

//IIC_Read_Byte
//ack=1  ACK
//ack=0  NACK
uint8_t IIC_Read_Byte(uint8_t ack)
{
	uint8_t i,receive=0;
	IIC_SDA(0);
	Delay(20);
	for(i=0;i<8;i++)
	{
		receive<<=1;
		SCL_OUT(0);
		Delay(40);
		SCL_OUT(1);
		Delay(40);
		if(GPIO_ReadInputDataBit(DEBUG_IIC_SDA_GPIO_PORT,DEBUG_IIC_SDA_PIN))
			receive++;
		Delay(40);
		SCL_OUT(0);
		Delay(40);
	}
	if(!ack) IIC_NAck();
	else IIC_Ack();
	return receive;
}

//EE_Write_Len
uint8_t EE_Write_Len(uint8_t *buf,uint8_t len)
{
	uint8_t i;
	IIC_SDA(1);
	Delay(40);
	SCL_OUT(1);
	Delay(40);
	SDA_OUT(1);
	Delay(40);
	IIC_Start();
	for(i=0;i<len;i++)
	{
		IIC_Send_Byte(buf[i]);
		if(IIC_Wait_Ack())
		{
			IIC_Stop();
		  return 1;
		}
	}
	IIC_Stop();
	return 0;
}


//EE_Write_Len
uint8_t EE_Read_Len(uint8_t *commbuf,uint8_t commlen,uint8_t *buf,uint8_t len)
{
	uint8_t i;
	IIC_Start();
	for(i=0;i<(commlen-1);i++)
	{
		IIC_Send_Byte(commbuf[i]);
		if(IIC_Wait_Ack())
		{
			IIC_Stop();
			return 1;
		}
	}
	IIC_Start();
	IIC_Send_Byte(commbuf[commlen-1]);
	if(IIC_Wait_Ack())
	{
		IIC_Stop();
		return 1;
	}
	
	while(len)
	{
		if(len==1) *buf=IIC_Read_Byte(0);//Nack
		else *buf=IIC_Read_Byte(1); //ack
		len--;
		buf++;
	}
	IIC_Stop();
	return 0;
}



